/**
 *	5.编写一个函数，把一个给定的值存储到一个整数中指定的几个位。它的原型如下：
 *	int store_bit_field(int original_value, int value_to_store,
 *      unsigned starting_bit, unsigned ending_bit);
 *	假定整数中的位是从右向左进行编号。因此，起始位的位置不会小于结束位的位置，为了更清楚的说明，函数应该返回下列值。
 *	原始值 	需要储存的位 	起始位 	结束位 	返回值
 *	0x0 	0x1 	4 	4 	0x10
 *	0xffff 	0x123 	15 	4 	0x123f
 *	0xffff 	0x123 	13 	9 	0xc7ff
 *	提示：把一个值存储到一个整数中指定的几个位分为5个步骤，以上表最后一行为例：
 *	1).创建一个掩码，它是一个值，其中需要存储的位置相对应的那几个位设置为1,此时掩码为
 *	00111110,00000000
 *	2).用掩码的反码对原值执行AND操作，将那几个位设置为0.原值1111111111111111,操作后变为
 *	11000001,11111111
 *	3).将新值左移，使它与需要存储的位对齐，新值00000001,00100011(0x123)，左移后变为
 *	01000110,00000000
 *	4).把移位后的值与掩码进行位AND操作，确保除那几个需要存储的位之外的其余位都设置为0,进行这个操作之后，值变为
 *	00000110,00000000
 *	5).把结果值与原值进行位OR操作，结果为(0xc7ff)
 *	11000111,11111111
 *	在所有任务中，最困难的是创建掩码，你一开始可以把～0这个值强制转换为无符号值，然后再对它进行移位。
**/

#include <stdio.h>

int strore_field(int original_value, int value_to_store, unsigned starting_bit, unsigned ending_bit);
int store_bit_field(int original_value, int value_to_store, unsigned starting_bit,unsigned ending_bit);

int main()
{
	printf("%x\n", strore_field(0x00, 0x1, 4, 4));
	printf("%x\n", strore_field(0xffff, 0x123, 15, 4));
	printf("%x\n", strore_field(0xffff, 0x123, 13, 9));
	printf("--------- 1.0 ------------\n");
	printf("%x\n",store_bit_field(0x0,0x1,4,4));
    	printf("%x\n",store_bit_field(0xffff,0x123,15,4));
    	printf("%x\n",store_bit_field(0xffff,0x123,13,9));

	return 0;
}

int strore_field(int original_value, int value_to_store, unsigned starting_bit, unsigned ending_bit)
{
	unsigned value = 0;
	unsigned make = 0;
	int temp = starting_bit - ending_bit + 1;
	
	// 1)
	while(temp)
	{
		make <<= 1;
		make |= 1;
		temp--;
	}
	make <<= ending_bit;

	// 2)
	value = (~make) & original_value;

	// 3)
	value_to_store =value_to_store << ending_bit;

	// 4)
	value_to_store &= make;

	// 5)
	value |= value_to_store;
	
	return value;
}

int store_bit_field(int original_value, int value_to_store,unsigned starting_bit,unsigned ending_bit)
{
    int value;
    int i = ending_bit;
    int unmask = 0;
    int mask = 0;
    int num = starting_bit - ending_bit + 1;
    while(num != 0){
        mask <<= 1;
        mask |= 1;
        num--;
    }
    while(i != 0){
        i--;
        mask <<= 1;
    }
    
    unmask = ~mask;
    original_value &= unmask;

    i = ending_bit;
    while(i != 0){
        i--;
        value_to_store <<= 1;
    }

    value = value_to_store & mask;

    value |= original_value;
    return value;
} 
